﻿#ifndef JZNODE_PROPERTY_BROWSER_H_
#define JZNODE_PROPERTY_BROWSER_H_

#include <QTreeWidget>
#include <QSharedPointer>
#include <QVariantList>
#include <functional>

class JZPropertyBrowser;
class JZPropertyWidget;
class JZProperty
{
public:
    enum {
        Prop_none = 0,
        Prop_Sub = 0x1,  //变化通知父prop发送消息，自身不发送
        Prop_NoEdit = 0x2,  //不能编辑
    };

    JZProperty(QString name,int dataType = QVariant::Invalid);

    const QString &name() const;
    void setName(const QString &name);
    
    int dataType() const;
    void setDataType(int dataType);    

    void setEnabled(bool flag);
    bool isEnabled() const;

    void setVisible(bool flag);
    bool isVisible();

    void setEditable(bool flag);
    bool isEditable();

    void addSubProperty(JZProperty *prop);    

    virtual void setValue(const QVariant &value);
    virtual const QVariant &value() const;

    void setRange(QVariant min, QVariant max);
    QVariant minValue();
    QVariant maxValue();

    virtual JZPropertyWidget *createEditWidget();
    virtual QIcon displayIcon();
    virtual QString displayText();

    JZProperty *parent();
    JZProperty *child(int index);
    
    int flag() const;
    void setFlag(int flag);
    bool isSub() const;

protected:
    friend JZPropertyBrowser;    
    
    QString m_name;
    QVariant m_value;
    QVariant m_min;
    QVariant m_max;
    int m_dataType;    
    int m_flag;

    bool m_enabled;
    QTreeWidgetItem *m_item;    
    QList<QSharedPointer<JZProperty>> m_childs;
    JZProperty* m_parent;
};

//JZPropertyGroup
class JZPropertyGroup : public JZProperty
{
public:
    JZPropertyGroup(QString name);
};

//JZPropertyEnum
class JZPropertyEnum : public JZProperty
{
public:
    JZPropertyEnum(QString name,int dataType, QVariantList enmuList, QStringList enumTextList);

    QVariantList enumList();
    QStringList enumTextList();
    virtual JZPropertyWidget *createEditWidget();

protected:
    QString displayText();

    QVariantList m_enumList;
    QStringList m_enumTextList;
};

//JZPropertyIntEnum
class JZPropertyIntEnum : public JZPropertyEnum
{
public:
    JZPropertyIntEnum(QString name, QList<int> enmuList, QStringList enumTextList);
};

//JZPropertyStringEnum
class JZPropertyStringEnum : public JZPropertyEnum
{
public:
    JZPropertyStringEnum(QString name, QStringList enumTextList);
};

//JZPropertyFilePath
class JZPropertyFilePath : public JZProperty
{
public:
    JZPropertyFilePath(QString name, QString filter);

    QString displayText();
    virtual JZPropertyWidget *createEditWidget();

    QString fileFilter();
    void setFileFilter(QString filter);

protected:
    QString m_fileFilter;
};

//JZPropertyDir
class JZPropertyDir : public JZProperty
{
public:
    JZPropertyDir(QString name);

    QString displayText();
    virtual JZPropertyWidget *createEditWidget();

protected:

};

//JZPropertyPoint
class JZPropertyPoint : public JZProperty
{
public:
    JZPropertyPoint(QString name, int dataType);

    virtual void setValue(const QVariant& value) override;
    virtual const QVariant& value() const override;

    QString displayText();
};

//JZPropertyRect
class JZPropertyRect : public JZProperty
{
public:
    JZPropertyRect(QString name, int dataType);

    virtual void setValue(const QVariant& value) override;
    virtual const QVariant& value() const override;

    QString displayText();
};

//JZPropertySize
class JZPropertySize : public JZProperty
{
public:
    JZPropertySize(QString name, int dataType);

    virtual void setValue(const QVariant& value) override;
    virtual const QVariant& value() const override;

    QString displayText();
};

//JZPropertyAlign
class JZPropertyAlign : public JZProperty
{
public:
    JZPropertyAlign(QString name);

    virtual void setValue(const QVariant& value) override;
    virtual const QVariant& value() const override;

    QString displayText();

protected:
    QStringList m_hText;
    QList<int> m_hValue;
    QStringList m_vText;
    QList<int> m_vValue;
};

//JZPropertyColor
class JZPropertyColor : public JZProperty
{
public:
    JZPropertyColor(QString name);

    virtual void setValue(const QVariant& value) override;
    virtual const QVariant& value() const override;

    QString displayText();
};



//JZPropertyManager
typedef std::function<JZProperty*(QString name)> CreatePropertyFunc;
class JZPropertyManager
{
public:
    static JZPropertyManager* instance();
    
    JZProperty *create(int qmetaid, QString name);
    void registProp(int qmetaid, CreatePropertyFunc creator);

protected:
    JZPropertyManager();
    ~JZPropertyManager();

    QMap<int, CreatePropertyFunc> m_propMap;
};

//JZPropertyBrowser
class JZPropertyBrowser : public QTreeWidget
{
    Q_OBJECT

public:
    JZPropertyBrowser();
    ~JZPropertyBrowser();

    void addProperty(JZProperty *prop);
    JZProperty *property(const QModelIndex &index);

    void clear();

signals:
    void valueChanged(JZProperty *prop,const QVariant &value);

protected:
    friend JZProperty;

    void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;    

    void createPropItem(QTreeWidgetItem *parent, JZProperty *prop);
    void setItemEnabled(QTreeWidgetItem *item,bool flag);
    void updateItem(QTreeWidgetItem *item);
    void updateProp(JZProperty *prop);

    JZProperty m_root;
    QMap<QTreeWidgetItem*, JZProperty*> m_propMap;
};


#endif // !JZNODE_PROPERTY_BROWSER_H_
